//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;

namespace OpenLS.Chart
{
    static class Enumerable
    {
        public static IEnumerable<TSource> Where<TSource>(IEnumerable<TSource> source, Predicate<TSource> predicate)
        {
            Contract.Assert(source != null);
            Contract.Assert(predicate != null);
            foreach (var tSource in source)
            {
                if (predicate(tSource))
                    yield return tSource;
            }
        }
        public static TSource FirstOrDefault<TSource>(IEnumerable<TSource> source, Predicate<TSource> predicate)
        {
            if (source == null)
                throw new ArgumentNullException("source");
            foreach (var tSource in source)
            {
                if (predicate(tSource))
                    return tSource;
            }
            return default(TSource);
        }


        public static double Count<T>(IEnumerable<T> enumerable)
        {
            int result = 0;
            foreach (var obj in enumerable)
            {
                result++;
            }
            return result;
        }

        public static IEnumerable<T> Take<T>(IEnumerable<T> source, int max)
        {
            int count = 0;
            foreach (var t in source)
            {
                if (count > max)
                    break;
                count++;
                yield return t;
            }
        }

        public static IEnumerable<TResult> Select<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, TResult> selector)
        {
            Contract.Assert(source != null);
            Contract.Assert(selector != null);
            return selectIterator(source, selector);
        }
        private static IEnumerable<TResult> selectIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, TResult> selector)
        {
            foreach (var sourceItem in source)
            {
                yield return selector(sourceItem);
            }
        }

    }
}